package services;

import java.awt.Color;

import javax.swing.JOptionPane;

import manager.Start;
import model.Part;
import enums.GameOverStateEnum;

public class StepService {

	/**
	 * The method adds the part that the user has chosen to the
	 * board
	 * @param part
	 */
	public static void addUserChoiceToBoard(Part part) {
		// check if the choice is valid (game not over, position is empty)
		if (!StepServiceHelper.isAdditionValid(part)) {
			JOptionPane.showMessageDialog(Start.getGame(), "Illegal move, please choose a different move",
				"Error", 0);
			return;
		}
		
		// set the part color
		Color turn  = Start.getState().getTurn();
		part.setColor(turn);
		
		// update the state if the game is over
		updateGameOverStateEnum(part);
		
		if (!StateService.isGameOver()) {
			// set state turn
			Color opponentTurn = 
					StepService.getOpponentTurn(turn);
			StateService.updateTurn(opponentTurn);
			
			// add the computer move
			addComputerChoiceToBoard();
		}
	}
	
	/**
	 * The method adds the part that the computer has chosen
	 * to the board
	 */
	public static void addComputerChoiceToBoard() {
		Part bestPart = ScoreService.getHighestScorePart();
		Color turn = Start.getState().getTurn();
		
		Start.getGame().getBoard().getParts()[bestPart.getRow()][bestPart.getColumn()].setColor(turn);
		
		updateGameOverStateEnum(Start.getGame().getBoard().getParts()[bestPart.getRow()][bestPart.getColumn()]);
		
		if (!StateService.isGameOver()) {
			Color otherTurn = 
					StepService.getOpponentTurn(turn);
			Start.getState().setTurn(otherTurn);
		}
	}
	
	public static void updateGameOverStateEnum(Part part) {
		boolean winner = StepService.isWinningStep(part);
		
		if (winner) {
			// get the winner color
			Color winnerColor = 
					StateService.currentTurnColor();
			// update the GameOverState
			StateService.updateGameOverEnum(winnerColor == Color.BLACK ? 
					GameOverStateEnum.BLACK_WINNER : GameOverStateEnum.WHITE_WINNER);
		}
		else if (StepService.isGameDrawStep()) {
			StateService.updateGameOverEnum(GameOverStateEnum.GAME_DRAW);
		}
	}
	
	/**
	 * The method will know if the game is over by draw
	 * after checking if all of the board has been chosen
	 * @return
	 */
	private static boolean isGameDrawStep() {
		return PartService.isAllBoardPartsChosen();
	}
	
	/**
	 * check if the current step is a winning step
	 * @param part
	 * @return
	 */
	private static boolean isWinningStep(Part part) {
		return PartService.isOneOfOpponentNeighborsSurrounded(part);
	}
	
	/**
	 * get the other player color
	 * @param turn
	 * @return
	 */
	public static Color getOpponentTurn(Color turn) {
		return turn == Color.BLACK ? Color.WHITE : Color.BLACK;
	}
}
